﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class GesturesIdentify : MonoBehaviour {
	List<Vector3> points = new List<Vector3>();
	public SkillGesturesData data;
	// Use this for initialization
	void Start () {
        FingerGestures.OnDragBegin += FingerGestures_OnDragBegin;
		FingerGestures.OnDragMove += FingerGestures_OnDragMove;
		FingerGestures.OnDragEnd += FingerGestures_OnDragEnd;
	}
	void FingerGestures_OnDragMove (Vector2 fingerPos, Vector2 delta)
	{
		points.Add (fingerPos);
	}
	void FingerGestures_OnDragBegin (Vector2 fingerPos, Vector2 startPos)
	{
		points.Clear ();
	}
	void FingerGestures_OnDragEnd (Vector2 fingerPos)
	{
		data = SkillGesturesRules.calculate (points);
	}
	void OnDrawGizmos(){
		Gizmos.color = Color.white;
		if (points.Count == 0)
			return;
		Gizmos.color = Color.red;
		Gizmos.DrawLine (points [0], points [points.Count - 1]);
		Gizmos.color = Color.green;
		for (int i = 0; i < points.Count - 1; i++) {
			Gizmos.DrawLine(points[i],points[i+1]);
			Gizmos.DrawSphere (points [i], 0.1f);
		}
		Gizmos.color = Color.yellow;
		if(data!=null)
			Gizmos.DrawLine (points [0]*0.5f+points[points.Count-1]*0.5f, points [0]*0.5f+points[points.Count-1]*0.5f + data.dircetion);
	}
}

[System.Serializable]
public class SkillGesturesData{
	/// <summary>
	/// 曲线弧度
	/// </summary>
	public float camber;
	/// <summary>
	/// 曲线方向
	/// </summary>
	public Vector3 dircetion;


	public float angle;
}

public class SkillGesturesRules{
	public static SkillGesturesData calculate(List<Vector3> points){
		SkillGesturesData data = new SkillGesturesData ();
		float length = 0;
		float max = 0;
		int maxid = 0;
		Vector3 cachedAveragePoint = Vector3.zero;
		cachedAveragePoint += points [0];
		cachedAveragePoint += points [points.Count - 1];

		data.angle = 0;
		for (int i = 1; i < points.Count - 1; i++) {
			data.angle+= Vector3.Angle (points [i] - points [i-1], points [i+1]-points [i]);

			float length2 = PointDistanceLine (points [i], points [0], points [points.Count - 1]);
			if (length2 > max) {
				maxid = i;
				max = length2;
			}
			length += length2;
			cachedAveragePoint += points [i];
		}



		data.camber = length / Vector2.Distance (points [points.Count - 1], points [0]);

		int _dir = ReturnPointInLineRightOrLeft (points [0], points [points.Count - 1], points [maxid]);
		data.dircetion = Quaternion.AngleAxis (_dir == -1?90:270, Vector3.forward) * (points [points.Count - 1] - points [0]);

		return data;
	}

	#region 点到直线距离
	public static float PointDistanceLine(Vector2 point,Vector2 linePointStart,Vector2 linePointEnd){
		float a, b, c;
		a = DPtToPtWin (linePointStart, linePointEnd);
		b = DPtToPtWin (linePointStart, point);
		c = DPtToPtWin (linePointEnd, point);

		float p = (a + b + c) / 2;// 半周长      
		float s = Mathf.Sqrt(p * (p - a) * (p - b) * (p - c));// 海伦公式求面积      
		float v = 2 * s / a;// 返回点到线的距离（利用三角形面积公式求高） 
		return v;
	}

	public static float DPtToPtWin(Vector2 pt0, Vector2 pt1)
	{
		return Mathf.Sqrt(Mathf.Pow((pt0.x - pt1.x), 2) + Mathf.Pow((pt0.y - pt1.y), 2));
	}
	#endregion
	#region 点在线的哪一侧
	public static int ReturnPointInLineRightOrLeft(Vector3 p1,Vector3 p2,Vector3 p3){
		float _ax = p2.x - p1.x;
		float _ay = p2.y - p1.y;
		float _bx = p3.x - p1.x;
		float _by = p3.y - p1.y;
		float judge = _ax * _by - _ay * _bx;
		if (judge > 0) {
			return -1;
		} else if (judge < 0) {
			return 1;
		} else {
			return 0;
		}
	}
	#endregion
}